
package controllers;


import javax.persistence.EntityManager;

import models.spider.actor.CrawlerService;
import models.spider.actor.Status.Details;
import models.spider.config.AAA;

import org.hibernate.search.jpa.FullTextEntityManager;

import play.data.Form;
import play.data.validation.Constraints.Min;
import play.data.validation.Constraints.Required;
import play.db.jpa.JPA;
import play.db.jpa.Transactional;
import play.mvc.Result;

/**
 * 
 * @author laurent@opprecht.info
 */
// @Restrict("admin")
public class Actor extends Application {

    public static class UrlEntry {

        @Required
        public String url;
    }

    public static class ThreadCount {

        @Required
        @Min(1)
        public int count;
    }

    public static CrawlerService crawler() {
        CrawlerService result = new CrawlerService(new AAA());
        return result;
    }

    @Transactional
    public static Result status() {
    	if(Authentication.isAdmin()) {
	        Details info = crawler().status();
	        return ok(views.html.actor.status.render(info));
	    }
		return redirect(routes.Authentication.login());
    }
    
    @Transactional
    public static Result index() {
    	if(Authentication.isAdmin()) {
	        Form<ThreadCount> form = play.data.Form.form(ThreadCount.class).bindFromRequest();
	
	        if (request().method() == "GET") {
	            return ok(views.html.actor.index.render(form));
	        }
	
	        if (form.hasErrors()) {
	            flash("error", "Invalid number");
	            return badRequest(views.html.actor.index.render(form));
	        } else {
	            int count = form.get().count;
	            return start(count);
	        }
	    }
		return redirect(routes.Authentication.login());
    }

    @Transactional
    public static Result start(final int count) {
    	if(Authentication.isAdmin()) {
	        crawler().start(count);
	        flash("success", "Started");
	        return redirect(routes.Actor.index());
	    }
		return redirect(routes.Authentication.login());        
    }

    @Transactional
    public static Result stop() {
    	if(Authentication.isAdmin()) {
	        crawler().stop();
	        flash("success", "Stopped");
	        return redirect(routes.Actor.index());
        }
    	return redirect(routes.Authentication.login());
    }

    @Transactional
    public static Result add() {
    	if(Authentication.isAdmin()) {
	        Form<UrlEntry> form = play.data.Form.form(UrlEntry.class).bindFromRequest();
	
	        if (request().method() == "GET") {
	            return ok(views.html.actor.add.render(form));
	        }
	
	        if (form.hasErrors()) {
	            return badRequest(views.html.actor.add.render(form));
	        } else {
	            String url = form.get().url;
	            crawler().add(url);
	            flash("message", "Added: " + url);
	            return redirect(routes.Actor.index());
	        }
	    }
		return redirect(routes.Authentication.login());
    }

    @Transactional
    public static Result refresh() {
    	if(Authentication.isAdmin()) {
	        Form<UrlEntry> form = play.data.Form.form(UrlEntry.class).bindFromRequest();
	
	        if (request().method() == "GET") {
	            return ok(views.html.actor.refresh.render(form));
	        }
	
	        if (form.hasErrors()) {
	            return badRequest(views.html.actor.refresh.render(form));
	        } else {
	            String url = form.get().url;
	            crawler().refresh(url);
	            flash("message", "Refreshed: " + url);
	            return redirect(routes.Actor.index());
	        }
	    }
		return redirect(routes.Authentication.login());
    }

    @Transactional
    public static Result indexText() {
    	if(Authentication.isAdmin()) {
	        EntityManager em = JPA.em();
	        FullTextEntityManager fullTextEntityManager = org.hibernate.search.jpa.Search.getFullTextEntityManager(em);
	        try {
	            fullTextEntityManager.createIndexer().startAndWait();
	        } catch (InterruptedException ex) {
	            flash("message", "Interupted");
	            return index();
	        }
	        flash("message", "done");
	        return index();
	    }
		return redirect(routes.Authentication.login());
    }
    
}
